package wifiunion.com.notice.widget.treedialog.utils;

import android.util.Log;
import android.view.View;

import com.lidroid.xutils.view.annotation.ViewInject;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import wifiunion.com.notice.Constants;
import wifiunion.com.notice.R;
import wifiunion.com.notice.widget.treedialog.annotation.TreeNodeChecked;
import wifiunion.com.notice.widget.treedialog.annotation.TreeNodeCommunityUuid;
import wifiunion.com.notice.widget.treedialog.annotation.TreeNodeName;
import wifiunion.com.notice.widget.treedialog.annotation.TreeNodeParentCommunityUuid;
import wifiunion.com.notice.widget.treedialog.annotation.TreeNodeUuid;
import wifiunion.com.notice.widget.treedialog.entity.Node;

/**
 * 参照 http://blog.csdn.net/lmj623565791/article/details/40212367
 */
public class TreeHelper {
    /**
     * 传入我们的普通bean，转化为我们排序后的Node
     *
     * @param datas
     * @param defaultExpandLevel
     * @return
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    public static <T> List<Node> getSortedNodes(List<T> datas, int defaultExpandLevel)
            throws IllegalArgumentException, IllegalAccessException

    {

        List<Node> result = new ArrayList<Node>();
        // 将用户数据转化为List<Node>
        List<Node> nodes = convetData2Node(datas);
        // 拿到根节点
        List<Node> rootNodes = getRootNodes(nodes);
        // 排序以及设置Node间关系
        for (Node node : rootNodes) {
            addNode(result, node, defaultExpandLevel, 1);
        }
        return result;
    }

    /**
     * 过滤出所有可见的Node
     *
     * @param nodes
     * @return
     */
    public static List<Node> filterVisibleNode(List<Node> nodes) {
        List<Node> result = new ArrayList<Node>();

        for (Node node : nodes) {
            // 如果为跟节点，或者上层目录为展开状态
            if (node.isRoot() || node.isParentExpand()) {
                setNodeIcon(node);
                result.add(node);
            }
        }
        return result;
    }

    /**
     * 将我们的数据转化为树的节点
     *
     * @param datas
     * @return
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     */
    private static <T> List<Node> convetData2Node(List<T> datas) throws IllegalArgumentException, IllegalAccessException

    {

        List<Node> nodes = new ArrayList<Node>();
        Node node = null;

        for (T t : datas) {
            String id = null;
            String pId = null;
            String label = null;
            int checked = -1;
            String uuid = null;
            Class<? extends Object> clazz = t.getClass();
            Field[] declaredFields = clazz.getDeclaredFields();
            for (Field f : declaredFields) {
                if (f.getAnnotation(TreeNodeCommunityUuid.class) != null) {
                    f.setAccessible(true);
                    id = (String) f.get(t);
                }
                if (f.getAnnotation(TreeNodeParentCommunityUuid.class) != null) {
                    f.setAccessible(true);
                    pId = (String) f.get(t);
                }
                if (f.getAnnotation(TreeNodeName.class) != null) {
                    f.setAccessible(true);
                    label = (String) f.get(t);
                }
                if (f.getAnnotation(TreeNodeChecked.class) != null) {
                    f.setAccessible(true);
                    checked = f.getInt(t);
                }
                if (f.getAnnotation(TreeNodeUuid.class) != null) {
                    f.setAccessible(true);
                    uuid = (String) f.get(t);
                }

                if (id != null && pId != null && label != null && checked != -1 && uuid != null) {
                    break;
                }
            }
            node = new Node(id, pId, label, checked, uuid);
            nodes.add(node);
        }

        /**
         * 设置Node间，父子关系;让每两个节点都比较一次，即可设置其中的关系
         */
        for (int i = 0; i < nodes.size(); i++) {
            Node n = nodes.get(i);
            for (int j = i + 1; j < nodes.size(); j++) {

                Node m = nodes.get(j);

                if (m.getUuid().startsWith(Constants.SUB_TREENODE_PREX) || n.getUuid().startsWith(Constants.SUB_TREENODE_PREX)) {
                    if (m.getpId().equals(n.getUuid())) {
                        n.getChildren().add(m);
                        m.setParent(n);
                    } else if (m.getUuid().equals(n.getpId())) {
                        m.getChildren().add(n);
                        n.setParent(m);
                    }
                } else {
                    if (m.getpId().equals(n.getUuid())) {
                        n.getChildren().add(m);
                        m.setParent(n);
                    } else if (m.getUuid().equals(n.getpId())) {
                        m.getChildren().add(n);
                        n.setParent(m);
                    }
//                    if (m.getpId().equals(n.getId())) {
//                        n.getChildren().add(m);
//                        m.setParent(n);
//                    } else if (m.getId().equals(n.getpId())) {
//                        m.getChildren().add(n);
//                        n.setParent(m);
//                    }
                }
            }
        }

        // 设置图片
        for (Node n : nodes) {
            setNodeIcon(n);
        }


        return nodes;
    }

    private static List<Node> getRootNodes(List<Node> nodes) {

        List<Node> root = new ArrayList<Node>();
        for (Node node : nodes) {
            if (node.isRoot())
                root.add(node);
        }
        return root;
    }

    /**
     * 把一个节点上的所有的内容都挂上去
     */
    private static void addNode(List<Node> nodes, Node node, int defaultExpandLeval, int currentLevel) {


        nodes.add(node);
        if (defaultExpandLeval >= currentLevel) {
            node.setExpand(true);
        }

        if (node.isLeaf())
            return;
        for (int i = 0; i < node.getChildren().size(); i++) {

            addNode(nodes, node.getChildren().get(i), defaultExpandLeval, currentLevel + 1);
        }
    }

    /**
     * 设置节点的图标
     *
     * @param node
     */
    private static void setNodeIcon(Node node) {
        if (node.getChildren().size() > 0 && node.isExpand()) {
            node.setIcon(R.drawable.open);
        } else if (node.getChildren().size() > 0 && !node.isExpand()) {
            node.setIcon(R.drawable.close);
        } else
            node.setIcon(-1);

    }


    public static void injectViews(View view) {
        Class<? extends View> object = view.getClass(); // 获取activity的Class
        Field[] fields = object.getDeclaredFields(); // 通过Class获取activity的所有字段
//        Log.e(Constants.TAG,"injectViews start ");
        for (Field field : fields) { // 遍历所有字段
            // 获取字段的注解，如果没有ViewInject注解，则返回null
            ViewInject viewInject = field.getAnnotation(ViewInject.class);
            if (viewInject != null) {
                int viewId = viewInject.value(); // 获取字段注解的参数，这就是我们传进去控件Id
                if (viewId != -1) {
                    try {
                        // 获取类中的findViewById方法，参数为int
//                        Method method = object.getMethod("findViewById", int.class);
                        // 执行该方法，返回一个Object类型的View实例
//                        Object resView = method.invoke(view, viewId);
                        field.setAccessible(true);
                        // 把字段的值设置为该View的实例
//                        field.set(view, resView);

                        field.set(view, view.findViewById(viewId));
                    } /*catch (NoSuchMethodException e) {
                        Log.e(Constants.TAG,"NoSuchMethodException "+e.getMessage());
                        e.printStackTrace();
                    } */ catch (IllegalAccessException e) {
                        Log.e(Constants.TAG, "IllegalAccessException " + e.getMessage());
                        e.printStackTrace();
                    } /*catch (InvocationTargetException e) {
                        Log.e(Constants.TAG,"InvocationTargetException "+e.getMessage());
                        e.printStackTrace();
                    }*/
                }
            }

//            Log.e(Constants.TAG,"injectViews end ");

        }
    }

}
